// 模拟第三方小米api，生成小米设备状态数据并提供设备控制方法
import {getBrandConfig} from "../../brand/getBrandConfig";
import {MockThirdParty} from "../../mock/MockThirdParty";
import {AppDataSource} from "../../config/database";
import axios from 'axios';
import { XiaomiNotifyBody } from '../../api/notify.route';
import { AccessToken } from '../../entity/Accesstoken';
import { XiaomiDevice } from "../../entity/XiaomiDevice";
import { Device } from "../../entity/Device";
import { In } from "typeorm/find-options/operator/In";

export class MockThirdPartyXiaomi extends MockThirdParty {
  private sensorLocks: Record<string, {
    temperature: number | null;
    humidity: number | null;
  }> = {}; // 存储温湿度锁定记录
  private deviceGroups: Map<string, string[]> = new Map(); // 存储分组设备关系

    constructor() {
        const config = getBrandConfig('xiaomi');
        super(config.app_id, config.app_secret);
        this.startXiaomiDeviceUpdater();
    }

  private startXiaomiDeviceUpdater(): void {
    const xiaomiDeviceRepo = AppDataSource.getRepository(XiaomiDevice);

    this.startDeviceStatusUpdater(
      this.generateXiaomiDeviceData.bind(this),
      this.pushXiaomiDeviceStatus.bind(this),
      xiaomiDeviceRepo
    );
  }

  public extractDeviceType(deviceId:string) {
    // 使用下划线分割设备ID
    const parts = deviceId.split('_');

    // 检查是否满足最小分割长度（至少3部分）
    if (parts.length < 3) {
      // 返回原ID或根据需求抛出错误
      return deviceId;
    }
    // 提取类型部分（从第2部分到倒数第2部分）
    const typeParts = parts.slice(1, -1);

    // 重新拼接为类型字符串
    return typeParts.join('_');
}

  // 初始化时加载分组关系
  async initDeviceGroups(userId: string) {
    const deviceRepo = AppDataSource.getRepository(Device);
    const devices = await deviceRepo.find({ where: { userId } });
    
    // 按分组ID组织设备
    const groupMap = new Map<string, string[]>();
    devices.forEach(device => {
      if (device.gid) {
        if (!groupMap.has(device.gid)) {
          groupMap.set(device.gid, []);
        }
        groupMap.get(device.gid)!.push(device.did);
      }
    });
    
    this.deviceGroups = groupMap;
  }

  // 获取同组设备
  private getGroupDevices(deviceId: string): string[] {
    // 默认组包含所有设备
    let groupDevices: string[] = [];
    
    // 查找设备所在分组
    for (const [gid, devices] of this.deviceGroups) {
      if (devices.includes(deviceId)) {
        groupDevices = devices;
        break;
      }
    }
    
    return groupDevices.length > 0 ? groupDevices : [...this.deviceGroups.values()].flat();
  }

  // 锁定/解锁温湿度方法
  public lockSensorValue(
    deviceId: string, 
    type: 'temperature' | 'humidity',
    value: number | null
  ): void {
    if (!this.sensorLocks[deviceId]) {
      this.sensorLocks[deviceId] = { temperature: null, humidity: null };
    }
    this.sensorLocks[deviceId][type] = value;
  }

  // 生成设备模拟数据
  public generateXiaomiDeviceData(deviceId: string): Record<string, any> {
    // const deviceType = deviceId.split('_')[1];
    const  deviceType = this.extractDeviceType(deviceId);

    // 检查是否有温湿度锁定
    const locks = this.sensorLocks[deviceId] || { 
      temperature: null, 
      humidity: null 
    };

    switch(deviceType) {
      // 小米温湿度计
      case 'mi_temp_hum_sensor':
        return {
          temperature: locks.temperature !== null 
            ? locks.temperature 
            : this.getRandomFloat(-10, 60, 1),
          humidity: locks.humidity !== null
            ? locks.humidity
            : this.getRandomInt(0, 100),
          // time: now.toISOString()
        };

      // 空气质量检测仪
      case 'mi_air_sensor':
        return {
          pm25: this.getRandomInt(0, 500),
          temperature: this.getRandomFloat(-10, 60, 1),
          humidity: this.getRandomInt(0, 100),
          // time: now.toISOString()
        };

      // 空调
      case 'mi_ac':
        return {
          online: Math.random() > 0.1, // 90%在线率
          target_temperature: this.getRandomFloat(16, 30, 1),
          fan_speed: ['low', 'medium', 'high', 'auto'][this.getRandomInt(0, 3)],
          mode: ['cool', 'heat', 'dry', 'fan'][this.getRandomInt(0, 3)],
          power: Math.random() > 0.5 ? 'ON' : 'OFF'
        };

      // 加湿器
      case 'mi_humidifier':
        const power = this.getRandomInt(0, 1);
        return {
          online: Math.random() > 0.1,
          power: power ? 1 : 0,
          status: power ?
            ['running', 'paused'][this.getRandomInt(0, 1)] : 'off',
          mode: ['auto', 'sleep', 'strong'][this.getRandomInt(0, 2)],
          target_humidity: this.getRandomInt(30, 80)
        };

      // 除湿器
      case 'mi_dehumidifier':
        return {
          online: Math.random() > 0.1,
          power: this.getRandomInt(0, 1) ? 1 : 0,
          status: this.getRandomInt(0, 1) ?
            ['running', 'paused'][this.getRandomInt(0, 1)] : 'off',
          mode: ['auto', 'sleep', 'dry'][this.getRandomInt(0, 2)],
          target_humidity: this.getRandomInt(30, 80)
        };

      // 空气净化器
      case 'mi_air_purifier':
        return {
          online: Math.random() > 0.1,
          power: this.getRandomInt(0, 1) ? 1 : 0,
          status: this.getRandomInt(0, 1) ?
            ['running', 'paused'][this.getRandomInt(0, 1)] : 'off',
          mode: ['auto', 'silent', 'strong'][this.getRandomInt(0, 2)],
          fan_level: this.getRandomInt(1, 3), // 1-3级风速
        };

      // 默认返回基础状态
      default:
        return {
          online: Math.random() > 0.1,
          power: Math.random() > 0.5 ? 'ON' : 'OFF',
          // time: now.toISOString()
        };
    }
  }

  // 小米设备状态推送方法（兼容服务端notify接口）
  async pushXiaomiDeviceStatus(
    deviceId: string,
    userId: string,
    data: Record<string, any>
  ): Promise<void> {
    const notifyUrl = 'http://localhost:3000/api/xiaomi/notify';

    try {
      // 严格匹配服务端接口的XiaomiNotifyBody格式
      const requestBody: XiaomiNotifyBody = {
        did: deviceId,
        event: 'prop.change',
        data
      };

      const response = await axios.post(notifyUrl, requestBody);

      if (response.data.code !== 200) {
        throw new Error(`推送失败: ${response.data.message}`);
      }

      console.log(`[Xiaomi] 设备 ${deviceId} 状态推送至服务端成功`, data);
    } catch (err) {
      if (err instanceof Error) {
        console.error(`[Xiaomi] 状态推送至服务端失败:`, err.message);
      } else {
        console.error(`[Xiaomi] 状态推送至服务端失败:`, err);
      }
      throw new Error('推送服务不可用');
    }
  }

  // 添加设备控制方法
async controlDevice(
  accessToken: string,
  did: string,
  control: { operation: string; value: any }
): Promise<{ code: number; status: number }> {
  // 验证access_token
  const tokenRepo = AppDataSource.getRepository(AccessToken);
  const tokenRecord = await tokenRepo.findOne({
    where: { token: accessToken, appId: getBrandConfig('xiaomi').app_id }
  });

  if (!tokenRecord || tokenRecord.expiresAt < new Date()) {
    throw new Error('903 授权过期');
  }

  // 检查设备是否存在
    const deviceList = await this.getDeviceList(accessToken);
    if (!deviceList.some(d => d.did === did)) {
      throw new Error('1300 设备不存在');
    }

    // 获取当前设备
    const currentDevice = deviceList.find(d => d.did === did);

    if (!currentDevice) {
      throw new Error('1300 Device not found');
    }

  // // 模拟属性验证
  // const validOperations = ['power', 'mode', 'target_temperature', 'fan_level'];
  // if (!validOperations.includes(control.operation)) {
  //   throw new Error('003 属性不存在');
  // }

  // 获取同组设备
  const groupDevices = this.getGroupDevices(did);
  
  // 查找同组的传感器设备
  const xiaomiDeviceRepo = AppDataSource.getRepository(XiaomiDevice);
  const sensors = await xiaomiDeviceRepo.find({
    where: {
      did: In(groupDevices),
      type: In(['mi_temp_hum_sensor', 'mi_air_sensor'])
    }
  });

  // 处理温度/湿度锁定
  if ((currentDevice.type.includes('ac') && control.operation === 'target_temperature') ||
      (currentDevice.type.includes('humidifier') && control.operation === 'target_humidity')) {
    sensors.forEach(sensor => {
      const lockType = currentDevice.type.includes('ac') ? 'temperature' : 'humidity';
      this.lockSensorValue(sensor.did, lockType, control.value);
    });
  } else if (control.operation === 'power' && control.value === 'OFF') {
    // 设备关闭时解除锁定
    const lockType = currentDevice.type.includes('ac') ? 'temperature' : 'humidity';
    sensors.forEach(sensor => {
      this.lockSensorValue(sensor.did, lockType, null);
    });
  }

  // 推送状态变更
  await this.pushXiaomiDeviceStatus(did, tokenRecord.userId, {
    [control.operation]: control.value
  });

  return {
    code: 200,
    status: 1 // 总是返回成功
  };
}


    // 辅助方法
    private getRandomInt(min: number, max: number): number {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }

    private getRandomFloat(min: number, max: number, decimals: number): number {
        const value = Math.random() * (max - min) + min;
        return parseFloat(value.toFixed(decimals));
    }
}
